﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Evolution
{
    class Game
    {
        //size of field
        private static int nsize = 30;
        private static int msize = 30;

        //two matrix. first matrix stores the state of the cells 
        //before passage of the original matrix and the new matrix stores
        //the state of the cells after passage
        private byte[,] matrix = new byte[nsize, msize];
        private byte[,] newmatrix = new byte[nsize, msize];

        //fill the matrix randomly, or 0 or 1
        private void Gen_matrix()
        {
            Random rnd = new Random();
            for (int i = 0; i < nsize; i++)
            {
                for (int j = 0; j < msize; j++)
                {
                    matrix[i, j] = (byte)rnd.Next(2);
                }
            }
        }

        private void Print_matrix()
        {
            for (int i = 0; i < nsize; i++)
            {
                for (int j = 0; j < msize; j++)
                {
                    switch (matrix[i, j])
                    {
                        case 0:
                            Console.Write(' ');
                            break;
                        case 1:
                            Console.Write('*');
                            break;
                    }
                }
                Console.WriteLine();
            }
        }
        //First, we calculate the boundary of the search neighborhood 
        //and the values at which cells change their state, and then 
        //going through each cell, fill in the new_matrix updated 
        // values ​​of the original matrix
        private void Change_newmatrix()
        {
            for (int i = 0; i < nsize; i++)
            {
                for (int j = 0; j < msize; j++)
                {
                    int newi = i - 1;
                    int newj = j - 1;
                    int newm = j + 2;
                    int newn = i + 2;
                    int val_born = 3;
                    int val_death = 9;
                    if ((j == 0) && (i > 0) && (i < nsize - 1))
                    {
                        newj = 0;
                        newm = 2;
                        val_death = 6;
                    }
                    if ((j == msize - 1) && (i > 0) && (i < nsize - 1))
                    {
                        newj = msize - 2;
                        newm = msize;
                        val_death = 6;
                    }
                    if ((i == 0) && (j > 0) && (j < msize - 1))
                    {
                        newi = 0;
                        newn = 2;
                        val_death = 6;
                    }
                    if ((i == nsize - 1) && (j > 0) && (j < nsize - 1))
                    {
                        newi = nsize - 2;
                        newn = nsize;
                        val_death = 6;
                    }
                    if ((i == 0) && (j == 0))
                    {
                        newi = 0;
                        newj = 0;
                        newn = 2;
                        newn = 2;
                        val_death = 4;
                    }
                    if ((i == 0) && (j == msize - 1))
                    {
                        newi = 0;
                        newj = msize - 2;
                        newn = 2;
                        newm = msize;
                        val_death = 4;
                    }
                    if ((i == nsize - 1) && (j == 0))
                    {
                        newi = nsize - 2;
                        newj = 0;
                        newn = nsize;
                        newm = 2;
                        val_death = 4;
                    }
                    if ((i == nsize - 1) && (j == nsize - 1))
                    {
                        newi = nsize - 2;
                        newj = msize - 2;
                        newn = nsize;
                        newm = msize;
                        val_death = 4;
                    }
                    int neighbors = 0;
                    switch (matrix[i, j])
                    {
                        case 0:
                            for (int i2 = newi; i2 < newn; i2++)
                            {
                                for (int j2 = newj; j2 < newm; j2++)
                                {
                                    if ((matrix[i2, j2] == 1))
                                    {
                                        neighbors++;
                                    }
                                }
                            }
                            if (neighbors >= val_born)
                            {
                                newmatrix[i, j] = 1;
                            }
                            else
                            {
                                newmatrix[i, j] = 0;
                            }
                            neighbors = 0;
                            break;
                        case 1:
                            for (int i2 = newi; i2 < newn; i2++)
                            {
                                for (int j2 = newj; j2 < newm; j2++)
                                {
                                    if ((matrix[i2, j2] == 1))
                                    {
                                        neighbors++;
                                    }
                                }
                            }
                            if (neighbors == val_death)
                            {
                                newmatrix[i, j] = 0;
                            }
                            else
                            {
                                newmatrix[i, j] = 1;
                            }
                            neighbors = 0;
                            break;
                    }
                }
            }
        }
        //Fill original matrix using values from newmatrix
        private void change_originalmatrix()
        {
            for (int i = 0; i < nsize; i++)
            {
                for (int j = 0; j < msize; j++)
                {
                    matrix[i, j] = newmatrix[i, j];
                }
            }
        }

        public void play()
        {
            Gen_matrix();
            Print_matrix();
            while (Console.ReadKey(true).Key == ConsoleKey.Spacebar)
            {
                Change_newmatrix();
                change_originalmatrix();
                Console.Clear();
                Print_matrix();
            }
        }
        
       static void Main(string[] args)
       {
           Game Game_evolution = new Game();
           Game_evolution.play();
       }
    }
}
